<template>
  <div class="upload-content">
    <div
      class="uplaod"
      :class="
        type === 'auto'
          ? 'auto'
          : type === 'small'
          ? 'small'
          : type === 'medium'
          ? 'medium'
          : ''
      "
    >
      <el-upload
        ref="uploadRef"
        :multiple="multiple"
        :accept="accept"
        :drag="drag"
        :list-type="listType"
        :limit="limit"
        :on-change="handleChange"
        :action="action"
        :auto-upload="autoUpload"
        :on-exceed="handleExceed"
        :disabled="disabled"
        v-model:file-list="fileList"
      >
        <el-icon>
          <Plus />
        </el-icon>
        <template #file="{ file }">
          <div class="flex-center">
            <!-- 图片 -->
            <template v-if="judgeType(file)">
              <img
                class="el-upload-list__item-thumbnail"
                :src="file.url"
                alt=""
              />
              <span class="el-upload-list__item-actions">
                <span
                  class="el-upload-list__item-preview"
                  @click="handlePreview(file)"
                >
                  <el-icon>
                    <View />
                  </el-icon>
                </span>
                <span
                  v-if="canRemove"
                  class="el-upload-list__item-delete"
                  @click="handleRemove(file)"
                >
                  <el-icon>
                    <Delete />
                  </el-icon>
                </span>
              </span>
            </template>
            <!-- 文档 -->
            <template v-else>
              <div class="other-text">
                {{ file.name || "文件预览" }}
              </div>
              <el-tooltip
                class="box-item"
                effect="dark"
                :content="file.name"
                placement="top"
              >
                <span class="el-upload-list__item-actions">
                  <span
                    class="el-upload-list__item-preview"
                    @click="handlePreview(file)"
                  >
                    <el-icon>
                      <View />
                    </el-icon>
                  </span>
                  <span
                    v-if="canRemove"
                    class="el-upload-list__item-delete"
                    @click="handleRemove(file)"
                  >
                    <el-icon>
                      <Delete />
                    </el-icon>
                  </span>
                </span>
              </el-tooltip>
            </template>
          </div>
        </template>
      </el-upload>
      <!-- 图片类型 -->
      <el-image-viewer
        v-if="imgShow"
        @close="imageClose"
        :url-list="imageUrlList"
        :initial-index="imageIndex"
      />
    </div>
    <p v-show="showSizeText">
      图片支持的格式为png/jepg/jpg，大小不超过{{ maxSize }}MB!
    </p>
    <div v-show="showLength" class="flex-start">
      <SvgIcon name="dot" /><span class="ml-[5px]">
        {{ fileList.length }}/{{ limit }}</span
      >
    </div>
  </div>
</template>
<script>
import { ref, defineComponent, watch, computed, nextTick } from "vue";
import { Plus } from "@element-plus/icons-vue";
import { ElMessage } from "element-plus";
import { uploadFile } from "@/api/index";
import { addFileWatermark } from "@/utils/common";

export default defineComponent({
  props: {
    showSizeText: {
      type: Boolean,
      default: false,
    },
    showLength: {
      type: Boolean,
      default: false,
    },
    multiple: {
      type: Boolean,
      default: false,
    },
    drag: {
      type: Boolean,
      default: false,
    },
    autoUpload: {
      type: Boolean,
      default: false,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    accept: {
      type: String,
      default: "",
    },
    listType: {
      type: String,
      default: "picture-card",
    },
    limit: {
      type: Number,
      default: 1,
    },
    maxSize: {
      type: Number,
      default: 10, //10MB
    },
    //default ,small ,medium
    type: {
      type: String,
      default: "default",
    },
    action: {
      type: String,
      default: "#",
    },
    previewList: {
      type: Array,
      default: [],
    },
    canRemove: {
      type: Boolean,
      default: true,
    },
    isUploadCallback: {
      type: Function,
      default: () => {},
    },
    internalUpload: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["changeFile"],
  name: "Upload",
  setup: (props, { emit }) => {
    let {
      limit,
      accept,
      maxSize,
      isUploadCallback,
      internalUpload,
      autoUpload,
    } = props;
    let fileList = ref([]);
    let uploadRef = ref(null);
    let imgShow = ref(false); //显示预览组件
    let imageUrlList = ref([]); //预览图片数组
    let imageIndex = ref(0); //图片预览数组下标
    let listImg = ref([]); //所有图片数组,用于对比上传删除前后的图片数组差集

    const formatLimit = (file) => {
      console.log("formatLimit", file, fileList.value);
      // 验证文件大小
      if (file.size > maxSize * 1024 * 1024) {
        ElMessage.error(`文件大小不能超过${maxSize}MB!`);
        return false;
      }

      // 验证文件类型
      if (!accept.split(",").includes(file.type)) {
        ElMessage.error(`仅支持${accept}格式！`);
        return false;
      }
      return true;
    };

    const handleChange = async (file) => {
      console.log("handleChange", file, fileList.value);
      // 仅当文件状态为 ready 时更新父组件
      if (file.status === "ready") {
        await nextTick();
        let flag = formatLimit(file.raw);
        !flag && (await handleRemove(file));
        if (judgeType(file)) {
          const newFile = await addFileWatermark(file.raw, file.raw.type);
          console.log("Watermark", newFile);
          fileList.value = fileList.value.map((f) =>
            f.uid === file.uid ? { ...file, ...newFile } : f
          );
        }
        if (internalUpload) {
          isUploadCallback(true);
          try {
            let res = await uplaod(file);
            if (res.flag) {
              const updatedFile = {
                ...file,
                id: res.id,
                url: res.url, // 假设接口返回完整url
              };
              // 更新fileList
              fileList.value = fileList.value.map((f) =>
                f.uid === file.uid ? updatedFile : f
              );
              await changeImage();
            } else {
              await handleRemove(file);
            }
          } catch (error) {
            await handleRemove(file);
          }
          isUploadCallback(false);
        } else {
          await changeImage();
        }
      }
    };

    //图片上传接口
    const uplaod = async (file) => {
      return new Promise(async (resolve, reject) => {
        let form = new FormData();
        form.append("file", file.raw);
        const res = await uploadFile(form);
        if (res.code === 200) {
          resolve({
            flag: true,
            url: res.data.url,
            id: res.data.id,
          });
        } else {
          resolve({
            flag: false,
          });
        }
      });
    };

    const handleRemove = async (file) => {
      console.log("handleRemove", file);
      uploadRef.value?.handleRemove(file);
      // 无论哪种类型文件，都触发changeImage
      await nextTick();
      await changeImage();
    };

    const handleExceed = async (file) => {
      console.log("handleExceed", file);
      let len = file.length;
      //将最新选择的图片覆盖之前的,此处的file文件属性貌似没有uid,向外抛出的
      if (limit === 1 && len === 1 && fileList.value.length > 0) {
        let lastFile = fileList.value[0];
        await handleRemove(lastFile);
        let firstFile = file[0];
        firstFile.uid = Date.now();
        uploadRef.value?.handleStart(firstFile);
      } else {
        ElMessage.error({
          message: `当前最多上传${limit}张图片！`,
          duration: 3000,
        });
      }
    };

    const handlePreview = (file) => {
      imageUrlList.value = fileList.value.map((v) => v.url);
      let index = fileList.value.findIndex(
        (v) => v.uid === file.uid && v.url === file.url
      );
      if (judgeType(file)) {
        imageIndex.value = index > -1 ? index : 0;
        imgShow.value = true;
      } else {
        window.open(file.url);
      }
    };

    const imageClose = () => {
      imageIndex.value = 0;
      imgShow.value = false;
    };

    const judgeType = (file) => {
      let imgList = ["gif", "jpeg", "jpg", "png", "bmp"];
      let str = file.name || file.url || "";
      let suffix = "";
      if (str) {
        if (props.isBase64) {
          if (str.startsWith("data:image")) {
            return true;
          }
          suffix = str.slice(str.lastIndexOf(".") + 1);
        } else {
          suffix = str.slice(str.lastIndexOf(".") + 1);
        }
      }
      return imgList.includes(suffix.toLowerCase());
    };

    const changeImage = () => {
      console.log("changeImage func", fileList.value, listImg.value);
      const currentUids = fileList.value.map((f) => f.uid);
      listImg.value = listImg.value.filter((f) => currentUids.includes(f.uid));
      console.log("listImg", listImg.value);
      fileList.value.forEach((f) => {
        if (!listImg.value.some((l) => l.uid === f.uid)) {
          listImg.value.push({ uid: f.uid, imgUrl: f.url });
        }
      });

      emit("changeFile", listImg.value);
    };

    watch(
      () => props.previewList,
      (newVal) => {
        fileList.value = newVal.map((f) => ({
          ...f,
          uid: Date.now(), // 生成唯一uid
          raw: null, // 标记为预览文件
        }));
      }
    );

    return {
      fileList,
      uploadRef,
      imgShow,
      imageIndex,
      imageUrlList,
      handleRemove,
      handleChange,
      handleExceed,
      handlePreview,
      judgeType,
      imageClose,
      formatLimit,
    };
  },
});
</script>

<style lang="scss" scoped>
.upload-content {
  width: 100%;
  text-align: left;
  margin: 5px 0 0;
}
.upload-content > p {
  color: rgba(0, 0, 0, 0.4);
  line-height: none;
  margin: 5px 0;
}

:deep(.el-upload-list__item-thumbnail) {
  object-fit: cover;
}
:deep(.el-upload-list__item) {
  border-radius: 16px;
}

:deep(.is-disabled) {
  .el-upload--picture-card {
    cursor: not-allowed !important;
  }
}

.other-text {
  // display: -webkit-box;
  // line-height: 1.5em;
  // -webkit-line-clamp: 4;
  // -webkit-box-orient: vertical;

  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.auto {
  :deep(.el-upload) {
    width: auto !important;
    height: 80px;
  }

  :deep(.el-upload-list__item) {
    width: auto !important;
    height: 80px;
  }
}

.small {
  :deep(.el-upload) {
    width: 102px;
    height: 102px;
  }

  :deep(.el-upload-list__item) {
    width: 102px;
    height: 102px;
  }
}

.medium {
  :deep(.el-upload) {
    width: 120px;
    height: 120px;
  }

  :deep(.el-upload-list__item) {
    width: 120px;
    height: 120px;
  }
}
.click-text {
  color: #bdbdbd;
}
.flex-center {
  display: flex;
  width: 100%;
  overflow: hidden;
  align-items: center;
  justify-content: center;
}
</style>    